package com.atguigu.gmall.payment.controller;

import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.atguigu.gmall.common.result.Result;
import com.atguigu.gmall.model.enums.PaymentStatus;
import com.atguigu.gmall.model.enums.PaymentType;
import com.atguigu.gmall.model.payment.PaymentInfo;
import com.atguigu.gmall.payment.config.AlipayConfig;
import com.atguigu.gmall.payment.service.AlipayService;
import com.atguigu.gmall.payment.service.PaymentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Controller
@RequestMapping("/api/payment/alipay")
public class AlipayController {

    @Autowired
    private AlipayService alipayService;
    @Autowired
    private PaymentService paymentService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Value("${app_id}")
    private String app_id;


    //生成二维码
    @RequestMapping("submit/{orderId}")
    @ResponseBody
    public String aliPay(@PathVariable Long orderId){
        String form = alipayService.createAliPay(orderId);
        return form;
    }

    //同步回调
    @RequestMapping("callback/return")
    public String callbackReturn(){
        return "redirect:"+ AlipayConfig.return_order_url;
    }
    //异步回调
    @PostMapping("callback/notify")
    @ResponseBody
    public String callbackNotify(@RequestParam Map<String, String> paramsMap){
        String outTradeNo = paramsMap.get("out_trade_no");
        String totalAmount = paramsMap.get("total_amount");
        String appId = paramsMap.get("app_id");
        String tradeStatus = paramsMap.get("trade_status");
        String notifyId = paramsMap.get("notify_id");

        Boolean singVerified = false;
        try {
            singVerified = AlipaySignature.rsaCheckV1(paramsMap, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        if (singVerified){
            //根据outTradeNo 以及支付类型 获取到paymentInfo
            PaymentInfo paymentInfoQuery = this.paymentService.getPaymentInfo(outTradeNo, PaymentType.ALIPAY.name());
            if (paymentInfoQuery == null ||new BigDecimal("0.01").compareTo(new BigDecimal(totalAmount))!=0||!appId.equals(app_id)){
                //返回失败
                return "failure";
            }
            Boolean result = this.redisTemplate.opsForValue().setIfAbsent(notifyId, "0", 1462, TimeUnit.MINUTES);
            if (!result){
                //说明发送过通知
                return "failure";
            }
            //判断状态
            if ("TRADE_SUCCESS".equals(tradeStatus)||"TRADE_FINISHED".equals(tradeStatus)){
                this.paymentService.paySuccess(outTradeNo,PaymentType.ALIPAY.name(),paramsMap);
                return "success";
            }
        }else{
            return "failure";
        }
        return "failure";
    }

    //退款
    @RequestMapping("refund/{orderId}")
    @ResponseBody
    public Result refund(@PathVariable Long orderId){
        Boolean flag = this.alipayService.refund(orderId);
        return Result.ok(flag);
    }
    //关闭支付宝交易记录
    @GetMapping("closePay/{orderId}")
    @ResponseBody
    public Result closePay(@PathVariable Long orderId){
        Boolean flag = this.alipayService.closePay(orderId);
        return Result.ok(flag);
    }

    //查询支付宝交易记录
    @GetMapping("checkPayment/{orderId}")
    @ResponseBody
    public Boolean checkPayment(@PathVariable Long orderId){
        Boolean flag = this.alipayService.checkPayment(orderId);
        return flag;
    }

    //查看paymentInfo
    @GetMapping("getPaymentInfo/{outTradeNo}")
    @ResponseBody
    public PaymentInfo getPaymentInfo(@PathVariable String outTradeNo){
        PaymentInfo paymentInfo = this.paymentService.getPaymentInfo(outTradeNo, PaymentType.ALIPAY.name());
        return paymentInfo;
    }
}
